#include <iostream>
#include <list>
#include <unordered_map>

// 观察者模式 （也叫观察者-监听者模式，发布-订阅模式）
// 主要关注的是一对多的关系 当该对象的状态发生改变时，
// 其他对象都能够收到相应的通知
//

class Observer {
public:
    virtual void handle(int msgid) = 0;
    virtual ~Observer() {
    }
};

class Observer1 : public Observer {
public:
    void handle(int msgid) override {
        switch (msgid) {
            case 2:
                std::cout << "o1 handling msg 2" << std::endl;
                break;
            case 3:
                std::cout << "o1 handling msg 3" << std::endl;
                break;
        }
    }
};
class Observer2 : public Observer {
    void handle(int msgid) override {
        switch (msgid) {
            case 1:
                std::cout << "o2 handling msg 1" << std::endl;
                break;
            case 3:
                std::cout << "o2 handling msg 3" << std::endl;
                break;
        }
    }
};
class Observer3 : public Observer {
    void handle(int msgid) override {
        switch (msgid) {
            case 1:
                std::cout << "o3 handling msg 1" << std::endl;
                break;
            case 2:
                std::cout << "o3 handling msg 2" << std::endl;
                break;
        }
    }
};

class Subject {
public:
    void addObserver(Observer *observer, int msgid) {
        _m[msgid].push_back(observer);
    }

    void update(int msgid) {
        auto it = _m.find(msgid);
        if (it != _m.end()) {
            for (auto p : it->second) {
                p->handle(msgid);
            }
        }
    }

private:
    std::unordered_map<int, std::list<Observer *>> _m;
};
int main() {
    Subject sub;
    Observer *o1 = new Observer1;
    Observer *o2 = new Observer2;
    Observer *o3 = new Observer3;

    sub.addObserver(o1, 2);
    sub.addObserver(o1, 3);

    sub.addObserver(o2, 1);
    sub.addObserver(o2, 3);

    sub.addObserver(o3, 1);
    sub.addObserver(o3, 2);

    for (int i = 1; i < 5; ++i) {
        sub.update(i);
    }
    delete o3;
    delete o2;
    delete o1;
}
